package com.example.qxfw.nyqx.controller;

import com.dmgis.util.DateTime;
import com.example.qxfw.common.SysResult;
import com.example.qxfw.common.entity.ny.BadCondition;
import com.example.qxfw.common.entity.ny.CropGrowdateIndexlib;
import com.example.qxfw.common.entity.qx.ForecastInfo;
import com.example.qxfw.common.entity.qx.SpecialSrvStation;
import com.example.qxfw.common.entity.qx.ThirtyYearDayStatics;
import com.example.qxfw.common.entity.qx.Weather;
import com.example.qxfw.common.entity.xt.SysConfig;
import com.example.qxfw.common.util.DateUtil;
import com.example.qxfw.common.util.FileUtil;
import com.example.qxfw.mongodb.hy.entity.HyPdfFile;
import com.example.qxfw.nyqx.dto.WeekDocDto;
import com.example.qxfw.nyqx.dto.WeekTemplateDto;
import com.example.qxfw.nyqx.service.BadConditionService;
import com.example.qxfw.nyqx.service.CropGrowdateIndexlibService;
import com.example.qxfw.nyqx.service.NytqybService;
import com.example.qxfw.qxxx.service.IssuerInfoService;
import com.example.qxfw.qxzs.service.SpecialSrvStationService;
import com.example.qxfw.ybzz.service.ForecastInfoService;
import com.example.qxfw.ybzz.service.SysConfigService;
import com.example.qxfw.ybzz.service.ThirtyYearDayStaticsService;
import com.example.qxfw.ybzz.service.WeatherService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(tags = "农气预报-农用天气预报")
@RestController()
@CrossOrigin
@RequestMapping("/AgriculturalWeatherForecastController")
public class AgriculturalWeatherForecastController {

    @Autowired
    private IssuerInfoService issuerInfoService;

    @Autowired
    private WeatherService weatherService;

    @Autowired
    private NytqybService nytqybService;

    @Autowired
    private CropGrowdateIndexlibService cropGrowdateIndexlibService;

    @Autowired
    private SpecialSrvStationService specialSrvStationService;

    @Autowired
    private ThirtyYearDayStaticsService thirtyYearDayStaticsService;

    @Autowired
    private ForecastInfoService forecastInfoService;

    @Autowired
    private BadConditionService badConditionService;

    @Autowired
    private SysConfigService sysConfigService;


    @Value("${city}")
    private String cityName;

    @ApiOperation("农气预报-获取期号")
    @GetMapping("/getDocNumber")
    public SysResult getWeekDocNumber(String type) {
        List<SysConfig> configList = sysConfigService.getList1();
        String dm_AgrDocNumber = "1";
        for (SysConfig sys : configList) {
            if (type.contains("周")) {
                if (sys.getParamname().equals("dm_AgrWeekDocNumber")) {
                    dm_AgrDocNumber = sys.getParamvalue();
                    break;
                }
            } else if (type.contains("月")) {
                if (sys.getParamname().equals("dm_AgrMonthDocNumber")) {
                    dm_AgrDocNumber = sys.getParamvalue();
                    break;
                }
            } else if (type.contains("灾害")) {
                if (sys.getParamname().equals("dm_AgrDisDocNumber")) {
                    dm_AgrDocNumber = sys.getParamvalue();
                    break;
                }
            }
        }
        int year = DateTime.now().GetYear();
        String DocNum = String.format("%s年%s期", year, String.format("%03d", Integer.parseInt(dm_AgrDocNumber)));
        return SysResult.success(DocNum);
    }


    @ApiOperation("农气预报-农用天气预报-获取签发人信息")
    @GetMapping("/getIssureUsername")
    public SysResult getIssureUsername(String permission) {
        List<String> userName1 = issuerInfoService.getUserName1(permission);
        return SysResult.success(userName1);
    }

    @ApiOperation("农气预报-农用天气预报-获取签发人电话")
    @GetMapping("/getIssurePhone")
    public SysResult getIssurePhone(String userName) {
        String phone = issuerInfoService.getPhone(userName);
        return SysResult.success(phone);
    }


    @ApiIgnore
    @GetMapping("/getWeather")
    public SysResult getWeather() {
        List<Weather> weather = weatherService.getWeather();
        return SysResult.success(weather);
    }

    @ApiIgnore
    @GetMapping("/getWeatherWind")
    public SysResult getWeatherWind() {
        List<Weather> wind = weatherService.getWind();
        return SysResult.success(wind);
    }

    @ApiIgnore
    @GetMapping("/getWeatherWindD")
    public SysResult getWeatherWindD() {
        List<Weather> windd = weatherService.getWindd();
        return SysResult.success(windd);
    }

    @ApiOperation("农气预报-农用天气预报-获取作物名称")
    @GetMapping("/getGrowDateCropName")
    public SysResult getGrowDateCropName() {
        List<String> cropName = cropGrowdateIndexlibService.getCropName();
        return SysResult.success(cropName);
    }

    @ApiOperation("农气预报-农用天气预报-根据作物名称获取种类")
    @GetMapping("/getGrowDateCropType")
    public SysResult getGrowDateCropType(String cropName) {
        List<String> type = cropGrowdateIndexlibService.getType(cropName);
        return SysResult.success(type);
    }

    @ApiOperation("农气预报-农用天气预报-获取一周天气文档模板内容")
    @GetMapping("/getWeekTemplate")
    public SysResult getWeekTemplate() throws IOException {
        WeekTemplateDto weekTemplate = nytqybService.getWeekTemplate();
        return SysResult.success(weekTemplate);
    }

    @ApiOperation("农气预报-农用天气预报-获取月报文档模板内容")
    @GetMapping("/getMonthTemplate")
    public SysResult getMonthTemplate() throws IOException {
        WeekTemplateDto weekTemplate = nytqybService.getMonthTemplate();
        return SysResult.success(weekTemplate);
    }

    @ApiOperation("农气预报-农用天气预报-获取气象预警文档模板内容")
    @GetMapping("/getQxWarnTemplate")
    public SysResult getQxWarnTemplate() throws IOException {
        WeekTemplateDto weekTemplate = nytqybService.getQxWarnTemplate();
        return SysResult.success(weekTemplate);
    }

    /**
     * 农气预报-农用天气预报-一周天气预报-指标库检索，更新具体预报和提示与建议
     *
     * @param stationId
     * @param dataTime
     * @return
     * @throws ParseException 需要市台指导报支持
     */
    @ApiOperation("农气预报-农用天气预报-一周天气预报-指标库检索，更新具体预报和提示与建议")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "stationId", value = "站点编号", dataType = "String", required = true),
            @ApiImplicitParam(name = "dataTime", value = "时间 yyyy-MM-dd HH:mm:ss", dataType = "String", required = true)
    })
    @GetMapping("/getIndexlib")
    public SysResult getIndexlib(@RequestParam(value = "stationId", required = true) String stationId,
                                 @RequestParam(value = "dataTime", required = true) String dataTime) throws ParseException {
        if (dataTime == "" || !dataTime.contains("-") || stationId == "")
            return SysResult.success("传参为空或不正确！");
        WeekTemplateDto weekTemplate = new WeekTemplateDto();
        // 1、得到特殊服务站点信息
        List<SpecialSrvStation> srvStations = specialSrvStationService.getList4(stationId);
        if (srvStations.size() > 0) {
            // 2、查询指标库信息，判定历年同期在指标库的情况，得到提示与建议
            String strTime = dataTime.split(" ")[1];
            String strDate = "2018/" + dataTime.substring(5, 7) + "/" + dataTime.substring(8, 10) + " " + strTime;
            String strDate2 = "2019/" + dataTime.substring(5, 7) + "/" + dataTime.substring(8, 10) + " " + strTime;
            String strDate3 = "2020/" + dataTime.substring(5, 7) + "/" + dataTime.substring(8, 10) + " " + strTime;
            List<CropGrowdateIndexlib> listcrop = cropGrowdateIndexlibService.getList3(strDate, strDate2, strDate3);
            String advise = "";
            if (listcrop.size() > 0) {
                for (int i = 0; i < listcrop.size(); i++) {
                    String strText = listcrop.get(i).getGrowdatename();
                    String strName = listcrop.get(i).getCropname().trim();
                    String strType = listcrop.get(i).getType();
//                    if (strText != null) {
                        advise = advise + strName + (strType == null ? "" : strType) + "当前处于" + strText + "\r\n";
//                    } else {
//                        advise = advise + strName + "当前处于" + strText + "\r\n";
//                    }
                }
            }
            weekTemplate.setAdvise(advise);
            String strWeather = getSevenForecast(dataTime);
            weekTemplate.setForecast(strWeather);
            weekTemplate.setTrend("");
        }

        return SysResult.success(weekTemplate);
    }

    @ApiOperation("农气预报-农用天气预报-农业气象预警-指标库检索，更新具体预报和提示与建议")
    @GetMapping("/getQxWarnIndexlib")
    public SysResult getQxWarnIndexlib(String stationId, String dataTime, String element) throws ParseException {
        if (dataTime == "" || !dataTime.contains("-") || stationId == "")
            return SysResult.success("传参为空或不正确！");
        WeekTemplateDto weekTemplate = new WeekTemplateDto();
        // 1、得到特殊服务站点信息
        List<SpecialSrvStation> srvStations = specialSrvStationService.getList4(stationId);
        if (srvStations.size() > 0) {
            String advise = "";
            double value = 0;
            int compare = 0;
            if (element.equals("暴雨")) {
                element = "降水";
                value = 40;
                compare = 0;
            } else if (element.equals("台风") || element.equals("大风")) {
                element = "风速";
                value = 12;
                compare = 0;
            } else if (element.equals("高温")) {
                element = "最高气温";
                value = 35;
                compare = 0;
            } else if (element.equals("霜冻")) {
                element = "最低气温";
                value = 5;
                compare = 1;
            } else if (element.equals("干旱")) {
                element = "CI";
                value = -1.8;
                compare = 1;
            } else if (element.equals("寒露风")) {
                element = "气温";
                value = 22;
                compare = 1;
            }
            List<CropGrowdateIndexlib> listcrop = cropGrowdateIndexlibService.getList4(dataTime.substring(5, 10));
            if (listcrop.size() > 0) {
                for (int i = 0; i < listcrop.size(); i++) {
                    String CropNum = listcrop.get(i).getIndexid();
                    String strText = listcrop.get(i).getGrowdatename();
                    String strName = listcrop.get(i).getCropname().trim();
                    String strType = listcrop.get(i).getType();
                    String strNSJYy = listcrop.get(i).getDefendmeasure();
                    List<BadCondition> listbad = badConditionService.getList(CropNum, element, String.valueOf(compare), String.valueOf(compare + 3), compare == 0 ? "<" : ">", String.valueOf(value));
                    if (listbad != null) {
                        advise = advise + strName + (strType == null ? "" : strType) + "当前处于" + strText + ";防御措施:" + strNSJYy + "\r\n";
                    }
                }
            }
            weekTemplate.setAdvise(advise);
            String strWeather = getSevenForecast(dataTime);
            weekTemplate.setForecast(strWeather);
        }

        return SysResult.success(weekTemplate);
    }

    public String getSevenForecast(String dataTime) throws ParseException {
        String strWeather = "";
        //查询七天天气预报
        String dateChar = dataTime;
        List<Weather> weathers = weatherService.getWeather();
        Map<String, String> mapweas = new HashMap<>();
        List<Weather> winds = weatherService.getWind();
        Map<String, String> mapwinds = new HashMap<>();
        List<Weather> windds = weatherService.getWindd();
        Map<String, String> mapwindds = new HashMap<>();
        for (Weather wea : weathers) {
            mapweas.put(wea.getWeatherid(), wea.getWeather());
        }
        for (Weather wea : winds) {
            mapwinds.put(wea.getWeatherid(), wea.getWind());
        }
        for (Weather wea : windds) {
            mapwindds.put(wea.getWeatherid(), wea.getWindd());
        }
        for (int k = 1; k <= 7; k++) {
            String timeChar = "20";
            Integer nTimes = 24 * k;
            List<ForecastInfo> forecastInfo = forecastInfoService.getForecastInfo(dateChar, timeChar, nTimes, cityName);
            if (forecastInfo.size() == 0) {
                forecastInfo = forecastInfoService.getForecastInfo(dateChar, "08", nTimes, cityName);
            }
            if (forecastInfo.size() > 0) {
                DateTime startD = DateTime.parseDate(dateChar);
                strWeather += startD.AddDays(k - 1).toDateString() + " ";
                if (forecastInfo.get(0).getWeather1().equals(forecastInfo.get(0).getWeather2())) {
                    strWeather += mapweas.get(String.format("%2s", forecastInfo.get(0).getWeather1()).replace(" ", "0"));

                } else {
                    strWeather += mapweas.get(String.format("%2s", forecastInfo.get(0).getWeather1()).replace(" ", "0"))
                            + "转" + mapweas.get(String.format("%2s", forecastInfo.get(0).getWeather2()).replace(" ", "0"));
                }
                strWeather += ",";
                if (forecastInfo.get(0).getWind1().equals(forecastInfo.get(0).getWind2())) {
                    strWeather += mapwinds.get(String.format("%2s", (int) Math.floor(forecastInfo.get(0).getWind1())).replace(" ", "0"));

                } else {
                    strWeather += mapwinds.get(String.format("%2s", (int) Math.floor(forecastInfo.get(0).getWind1())).replace(" ", "0"))
                            + "转" + mapwinds.get(String.format("%2s", (int) Math.floor(forecastInfo.get(0).getWind2())).replace(" ", "0"));
                }
                strWeather += ",";
                if (forecastInfo.get(0).getWindd1().equals(forecastInfo.get(0).getWindd2())) {
                    strWeather += mapwindds.get(String.format("%2s", forecastInfo.get(0).getWindd1()).replace(" ", "0"));

                } else {
                    strWeather += mapwindds.get(String.format("%2s", forecastInfo.get(0).getWindd1()).replace(" ", "0"))
                            + "转" + mapwindds.get(String.format("%2s", forecastInfo.get(0).getWindd2()).replace(" ", "0"));
                }
                strWeather += ",";
                strWeather += forecastInfo.get(0).getMintemp() + "~" + forecastInfo.get(0).getMaxtemp() + "℃";
                strWeather += ";";
            }
        }
        return strWeather;
    }

    @ApiOperation("农气预报-农用天气预报-历年同期查询")
    @GetMapping("/getHistoryData")
    public SysResult getHistoryData(String stationId, String startDate, String endDate) throws IOException, ParseException {
        if (startDate == "" || endDate == "" || stationId == "")
            return SysResult.success("传参为空或不正确！");

        DecimalFormat df = new DecimalFormat("0.00");//将数值格式为小数点后两位

        Map<String, String> maprlt = new HashMap<String, String>();
        DateTime startD = DateTime.parseDate(startDate);
        DateTime endD = DateTime.parseDate(endDate);
        int day1 = DateUtil.yearMonthDay(startD.GetYear(), startD.GetMonth(), startD.GetDay());
        int day2 = DateUtil.yearMonthDay(endD.GetYear(), endD.GetMonth(), endD.GetDay());
        List<ThirtyYearDayStatics> list1 = thirtyYearDayStaticsService.getList2(day1, day2, stationId);
        if (list1.size() > 0) {
            maprlt.put("最高温度", list1.get(0) == null ? "0.0℃" : df.format(list1.get(0).getYearareadayavgmaxtemp()) + "℃");
            maprlt.put("最低温度", list1.get(0) == null ? "0.0℃" : df.format(list1.get(0).getYearareadayavgmintemp()) + "℃");
            maprlt.put("平均气温", list1.get(0) == null ? "0.0℃" : df.format(list1.get(0).getYearareadayavgtemp()) + "℃");
        }

        String avgRain2 = thirtyYearDayStaticsService.getAvgRain3(day1, day2, stationId);
        if (avgRain2 != null && avgRain2 != "") {
            maprlt.put("平均雨量", df.format(Double.parseDouble(avgRain2)) + "mm");
        } else
            maprlt.put("平均雨量", "0.0mm");

        String maxRain1 = thirtyYearDayStaticsService.getMaxRain(day1, day2, stationId);
        if (maxRain1 != null && maxRain1 != "") {
            maprlt.put("最大雨量", df.format(Double.parseDouble(maxRain1)) + "mm");
        } else
            maprlt.put("最大雨量", "0.0mm");

        return SysResult.success(maprlt);
    }

    @ApiOperation("农气预报-农用天气预报-一周天气预报产品生成")
    @PostMapping("/createWeekDoc")
    public void createWeekDoc(@RequestBody WeekDocDto weekDocDto, HttpServletResponse response) throws IOException, ParseException {
        ApplicationHome applicationHome = new ApplicationHome(FileUtil.class);
        String filename = "一周天气文档";
        String filePath = applicationHome.getDir().getParentFile().getParentFile().getAbsolutePath() + "\\src\\main\\resources\\temp\\" + filename + ".pdf";
        nytqybService.createWeekDoc(weekDocDto, filename);
        InputStream inputStream = Files.newInputStream(Paths.get(filePath));
        response.setContentType("application/octet-stream");
        response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("" + filename + ".pdf", "UTF-8"));
        ServletOutputStream outputStream = response.getOutputStream();
        byte[] b = new byte[1024];
        int len;
        while ((len = inputStream.read(b)) > 0) {
            outputStream.write(b, 0, len);
        }
        inputStream.close();
    }

    @ApiOperation("农气预报-农用天气预报-月预报产品生成")
    @PostMapping("/createMonthDoc")
    public void createMonthDoc(@RequestBody WeekDocDto weekDocDto, HttpServletResponse response) throws IOException, ParseException {
        ApplicationHome applicationHome = new ApplicationHome(FileUtil.class);
        String filename = "月农用天气预报";
        String filePath = applicationHome.getDir().getParentFile().getParentFile().getAbsolutePath() + "\\src\\main\\resources\\temp\\" + filename + ".pdf";
        nytqybService.createWeekDoc(weekDocDto, filename);
        InputStream inputStream = Files.newInputStream(Paths.get(filePath));
        response.setContentType("application/octet-stream");
        response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("" + filename + ".pdf", "UTF-8"));
        ServletOutputStream outputStream = response.getOutputStream();
        byte[] b = new byte[1024];
        int len;
        while ((len = inputStream.read(b)) > 0) {
            outputStream.write(b, 0, len);
        }
        inputStream.close();
    }

    @ApiOperation("农气预报-农用天气预报-农业气象灾害预警产品制作")
    @PostMapping("/createQxWarnDoc")
    public void createQxWarnDoc(@RequestBody WeekDocDto weekDocDto, HttpServletResponse response) throws IOException, ParseException {
        ApplicationHome applicationHome = new ApplicationHome(FileUtil.class);
        String filename = "农业气象灾害预警";
        String filePath = applicationHome.getDir().getParentFile().getParentFile().getAbsolutePath() + "\\src\\main\\resources\\temp\\" + filename + ".pdf";
        nytqybService.createWeekDoc(weekDocDto, filename);
        InputStream inputStream = Files.newInputStream(Paths.get(filePath));
        response.setContentType("application/octet-stream");
        response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("" + filename + ".pdf", "UTF-8"));
        ServletOutputStream outputStream = response.getOutputStream();
        byte[] b = new byte[1024];
        int len;
        while ((len = inputStream.read(b)) > 0) {
            outputStream.write(b, 0, len);
        }
        inputStream.close();
    }


    /**
     * 得到最近的周报 月报
     *
     * @param filetype 一周天气文档 月农用天气预报
     * @param response
     * @throws IOException
     * @throws ParseException
     */
    @ApiOperation("农气预报-农用天气预报-得到最近的周报/月报")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "filetype", value = "文件类型：一周天气文档/月农用天气预报", dataType = "String", required = true)
    })
//    @PostMapping("/getLastWeekDoc")
    @GetMapping("/getLastWeekDoc")
    public void getLastDoc(String filetype, HttpServletResponse response) throws IOException, ParseException {
        HyPdfFile pdfFile = nytqybService.getLastWeekDoc(filetype);
        if (pdfFile != null) {
            InputStream inputStream = new ByteArrayInputStream(pdfFile.getData());
            response.setContentType("application/octet-stream");
            response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("doc_File", "UTF-8"));
            ServletOutputStream outputStream = response.getOutputStream();
            byte[] b = new byte[1024];
            int len;
            while ((len = inputStream.read(b)) > 0) {
                outputStream.write(b, 0, len);
            }
            inputStream.close();
        } else {
            System.out.println("文件不存在");
        }
    }
}
